using MicroMsg.Common.Event;
using MicroMsg.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MicroMsg.Storage
{
	public class ChatMsgTable : StorageTable<ChatMsg, int>
	{
		private const string TAG = "ChatMsgTable";
		private const int cache_size = 1000;
		public const int ON_ITEM_ADD = 0;
		public const int ON_ITEM_DEL = 1;
		public const int ON_ITEM_MOD = 2;
		private Dictionary<int, ChatMsg> mapCache = new Dictionary<int, ChatMsg>();
		private int minCacheID;
		private int maxCacheID;
		private Dictionary<int, int> mapBySvrID = new Dictionary<int, int>();
		private int minLocalID;
		private string msgTableName = "ChatMsg";
		private bool lockEvent;
		public ChatMsgTable(string tabName = null, int id_base = 1) : base((ChatMsg msg) => msg.nMsgLocalID)
		{
			if (tabName != null)
			{
				this.msgTableName = tabName;
				base.setMapping(new ChatMsgMapping(tabName));
			}
			this.minLocalID = id_base;
		}
		protected override bool init()
		{
			if (!base.init())
			{
				return false;
			}
			this.mapCache.Clear();
			this.mapBySvrID.Clear();
			if (base.IsEmpty())
			{
				this.minCacheID = this.minLocalID;
				this.maxCacheID = this.minCacheID;
				return true;
			}
			int num = base.count();
			int start = Math.Max(0, num - 1000);
			int num2 = Math.Min(1000, num);
			List<ChatMsg> list = base.getList(start, num2);
			if (list == null || list.get_Count() < num2)
			{
				Log.smethod_5("storage", "init msg cache fail");
				DebugEx.debugBreak();
			}
			using (List<ChatMsg>.Enumerator enumerator = list.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					ChatMsg current = enumerator.get_Current();
					this.mapCache.set_Item(current.nMsgLocalID, current);
					this.mapBySvrID.set_Item(current.nMsgSvrID, current.nMsgLocalID);
				}
			}
			this.minCacheID = Enumerable.Min<ChatMsg>(list, (ChatMsg chatMsg_0) => chatMsg_0.nMsgLocalID);
			this.maxCacheID = Enumerable.Max<ChatMsg>(list, (ChatMsg chatMsg_0) => chatMsg_0.nMsgLocalID);
			Log.smethod_5("ChatMsgTable", string.Concat(new object[]
			{
				this.msgTableName,
				"init  chatmsg cache total=",
				num,
				" read num=",
				num2,
				"  min_id=",
				this.minCacheID,
				" max_id=",
				this.maxCacheID,
				" time=",
				DebugEx.getTimeSpan()
			}));
			return true;
		}
		public ChatMsg getMsg(int nMsgLocalID)
		{
			if (!base.isReady())
			{
				return null;
			}
			if (this.mapCache.ContainsKey(nMsgLocalID))
			{
				return this.mapCache.get_Item(nMsgLocalID);
			}
			return base.method_1(nMsgLocalID);
		}
		public ChatMsg getBySvrID(int nMsgSvrID)
		{
			if (!base.isReady())
			{
				return null;
			}
			if (this.mapBySvrID.ContainsKey(nMsgSvrID))
			{
				int num = this.mapBySvrID.get_Item(nMsgSvrID);
				if (!this.mapCache.ContainsKey(num))
				{
					Log.smethod_5("storage", string.Concat(new object[]
					{
						"map error msg svrid =",
						nMsgSvrID,
						" local id= ",
						num
					}));
					DebugEx.debugBreak();
				}
				return this.mapCache.get_Item(num);
			}
			return base.method_2((ChatMsg m) => m.nMsgSvrID == nMsgSvrID);
		}
		public bool addMsg(ChatMsg chatMsg_0)
		{
			if (chatMsg_0 == null || !base.isReady())
			{
				return false;
			}
			if (chatMsg_0.nMsgLocalID != 0)
			{
				Log.smethod_5("ChatMsgTable", "re add exist msg " + chatMsg_0.nMsgLocalID);
				DebugEx.debugBreak();
				return false;
			}
			chatMsg_0.nMsgLocalID = ++this.maxCacheID;
			this.mapCache.set_Item(chatMsg_0.nMsgLocalID, chatMsg_0);
			this.mapBySvrID.set_Item(chatMsg_0.nMsgSvrID, chatMsg_0.nMsgLocalID);
			this.cacheNotify(0, chatMsg_0);
			return true;
		}
		public bool delMsg(ChatMsg chatMsg_0)
		{
			if (chatMsg_0 == null || !base.isReady())
			{
				return false;
			}
			if (this.mapCache.ContainsKey(chatMsg_0.nMsgLocalID))
			{
				chatMsg_0 = this.mapCache.get_Item(chatMsg_0.nMsgLocalID);
				this.mapCache.Remove(chatMsg_0.nMsgLocalID);
				this.mapBySvrID.Remove(chatMsg_0.nMsgSvrID);
				this.cacheNotify(1, chatMsg_0);
				return true;
			}
			return base.method_4(chatMsg_0);
		}
		public bool delMsgBySvrID(int nMsgSvrID)
		{
			if (!base.isReady())
			{
				return false;
			}
			if (this.mapBySvrID.ContainsKey(nMsgSvrID))
			{
				ChatMsg msg = this.getMsg(this.mapBySvrID.get_Item(nMsgSvrID));
				return this.delMsg(msg);
			}
			return true;
		}
		public void delByTalker(string talker)
		{
			if (!string.IsNullOrEmpty(talker) && base.isReady())
			{
				List<ChatMsg> list = Enumerable.ToList<ChatMsg>(Enumerable.OrderBy<ChatMsg, int>(Enumerable.Select<KeyValuePair<int, ChatMsg>, ChatMsg>(Enumerable.Where<KeyValuePair<int, ChatMsg>>(this.mapCache, (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value().strTalker == talker), (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value()), (ChatMsg chatMsg_0) => chatMsg_0.nMsgLocalID));
				using (List<ChatMsg>.Enumerator enumerator = list.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						ChatMsg current = enumerator.get_Current();
						this.delMsg(current);
					}
				}
				base.method_6((ChatMsg m) => m.strTalker == talker && m.nMsgLocalID < this.minCacheID);
				return;
			}
		}
		public bool modifyMsg(ChatMsg item)
		{
			if (item == null || item.nMsgLocalID == 0 || !base.isReady())
			{
				return false;
			}
			if (this.mapCache.ContainsKey(item.nMsgLocalID))
			{
				ChatMsg chatMsg = this.mapCache.get_Item(item.nMsgLocalID);
				if (chatMsg != item)
				{
					chatMsg.merge(item);
					chatMsg.modify = item.modify;
				}
				this.mapBySvrID.set_Item(chatMsg.nMsgSvrID, chatMsg.nMsgLocalID);
				this.cacheNotify(2, chatMsg);
				return true;
			}
			return base.modify(item);
		}
		public bool updateMsg(ChatMsg chatMsg_0)
		{
			if (chatMsg_0 == null || !base.isReady())
			{
				return false;
			}
			if (chatMsg_0.nMsgLocalID == 0)
			{
				return this.addMsg(chatMsg_0);
			}
			if (this.mapCache.ContainsKey(chatMsg_0.nMsgLocalID))
			{
				return this.modifyMsg(chatMsg_0);
			}
			if (chatMsg_0.nMsgLocalID < this.minCacheID)
			{
				return base.update(chatMsg_0);
			}
			return this.addMsg(chatMsg_0);
		}
		private int MsgNumInDB(string talker)
		{
			return base.method_0((ChatMsg m) => m.strTalker == talker && m.nMsgLocalID < this.minCacheID);
		}
		private int MsgNumInCache(string talker)
		{
			return Enumerable.Count<KeyValuePair<int, ChatMsg>>(Enumerable.Where<KeyValuePair<int, ChatMsg>>(this.mapCache, (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value().strTalker == talker));
		}
		public int getMsgNum(string talker)
		{
			if (!string.IsNullOrEmpty(talker) && base.isReady())
			{
				return this.MsgNumInCache(talker) + this.MsgNumInDB(talker);
			}
			return 0;
		}
		public List<ChatMsg> getMsgList(string talker, int start, int int_0)
		{
			if (string.IsNullOrEmpty(talker) || int_0 <= 0 || !base.isReady())
			{
				return null;
			}
			int num = this.MsgNumInDB(talker);
			if (start + int_0 <= num)
			{
				return base.getList((ChatMsg m) => m.strTalker == talker && m.nMsgLocalID < this.minCacheID, start, int_0);
			}
			if (start >= num)
			{
				return Enumerable.ToList<ChatMsg>(Enumerable.Take<ChatMsg>(Enumerable.Skip<ChatMsg>(Enumerable.OrderBy<ChatMsg, int>(Enumerable.Select<KeyValuePair<int, ChatMsg>, ChatMsg>(Enumerable.Where<KeyValuePair<int, ChatMsg>>(this.mapCache, (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value().strTalker == talker), (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value()), (ChatMsg chatMsg_0) => chatMsg_0.nMsgLocalID), start - num), int_0));
			}
			int num2 = start + int_0 - num;
			List<ChatMsg> list = Enumerable.ToList<ChatMsg>(Enumerable.Take<ChatMsg>(Enumerable.Select<KeyValuePair<int, ChatMsg>, ChatMsg>(Enumerable.Where<KeyValuePair<int, ChatMsg>>(this.mapCache, (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value().strTalker == talker), (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value()), num2));
			int int_ = int_0 - num2;
			List<ChatMsg> list2 = base.getList((ChatMsg m) => m.strTalker == talker && m.nMsgLocalID < this.minCacheID, start, int_);
			if (list != null && list.get_Count() > 0)
			{
				list2.AddRange(list);
			}
			return list2;
		}
		public List<ChatMsg> searhCacheMsg(int nMsgType, int nMsgStatus, int isSender = 1)
		{
			if (!base.isReady())
			{
				return null;
			}
			return Enumerable.ToList<ChatMsg>(Enumerable.OrderBy<ChatMsg, int>(Enumerable.Select<KeyValuePair<int, ChatMsg>, ChatMsg>(Enumerable.Where<KeyValuePair<int, ChatMsg>>(this.mapCache, (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value().nMsgType == nMsgType && keyValuePair_0.get_Value().nStatus == nMsgStatus && keyValuePair_0.get_Value().nIsSender == isSender), (KeyValuePair<int, ChatMsg> keyValuePair_0) => keyValuePair_0.get_Value()), (ChatMsg chatMsg_0) => chatMsg_0.nMsgLocalID));
		}
		public bool updateBySvrID(ChatMsg item)
		{
			if (item == null || !base.isReady())
			{
				return false;
			}
			if (this.mapBySvrID.ContainsKey(item.nMsgSvrID))
			{
				item.nMsgLocalID = this.mapBySvrID.get_Item(item.nMsgSvrID);
				return this.modifyMsg(item);
			}
			return this.addMsg(item);
		}
		public List<ChatMsg> patch_get_qmsg()
		{
			if (!base.isReady())
			{
				return null;
			}
			return base.search((ChatMsg msg) => msg.strTalker != null && msg.strTalker.EndsWith("@qqim"), -1, -1);
		}
		public void clearAllMsg()
		{
			this.lockEvent = true;
			base.onFlush();
			this.mapCache.Clear();
			this.mapBySvrID.Clear();
			base.clearAll();
			this.lockEvent = false;
		}
		public override void notify(int operation, ChatMsg item)
		{
			if (this.lockEvent)
			{
				return;
			}
			if (item.nMsgLocalID >= this.minCacheID)
			{
				return;
			}
			EventCenter.postCombineEvent(EventConst.ON_STORAGE_CHAT_MSG_ADD + operation, item);
		}
		public void cacheNotify(int operation, ChatMsg item)
		{
			base.dataChangeRequest((DataOper)operation, item.clone<ChatMsg>());
			if (this.lockEvent)
			{
				return;
			}
			EventCenter.postCombineEvent(EventConst.ON_STORAGE_CHAT_MSG_ADD + operation, item);
		}
		public void dumpTable()
		{
			base.isReady();
		}
	}
}
